#pragma once
#include <string>
#include <map>
#include <vector>
#include <QtCore/qglobal.h>

using namespace std;

/*
* namelen name datalen data namelen
*/
#define KEY_LEN 64

typedef struct _SDataHeader
{
    qint64			_nKeyLen;
    qint64			_dataLen;
	char			*_pKey;
    char			*_pData;

    _SDataHeader();
    _SDataHeader(const _SDataHeader& other);
    _SDataHeader& operator=(const _SDataHeader& other);
}DATAHEADER, *PDATAHEADER;

class CCommand
{
public:
	CCommand();
	~CCommand();
public:
	void SetCommandKey(const char* commandkey);
	void SetCommandType(int eType, const char* commandkey);
	void SetParameteInt(const char* name, int nValue);
    void SetParameteBigInt(const char* name, qint64 llValue);
	void SetParameteDouble(const char*  name, double dValue);
	void SetParameteString(const char*  name, const char*  strValue);
	void SetOtherData(const char* name, void* pData, int nDatalen);

	const char* GetCommand();
	int GetCommandSize();

	int GetKVStrSize();
	bool GetKVStr(char* pOutStr, int nCapacityLen);

	void GetKeys(
		char* argKeys[],
		int &nCount);
	void ReleaseKeys(char* argKeys[], int nCount);
public:
	void Assignment(const char* commandstr);
	void AssignmentKV(const char* commandstr);
public:
	int GetCommandType();
	const char* GetCommandKey();
	int GetParameteInt(const char* name, int nDefaultValue);
	double GetParameteDouble(const char*  name, double dDefaultValue);
	const char* GetParameteString(const char*  name, const char*  strDefaultValue);
	const char* GetOtherData(const char*  name, int& nDataLen);

	bool HaveAttribute(const char* name);
public:
	void Data2File(FILE* pFile);
	void LoadFromFile(FILE* pFile, int nLen);

private:
	void AddData2BufferInt(
		string keystr,
		int nValue);
	void AddData2BufferDouble(
		string keystr,
		double dValue);
	void AddData2BufferBigInt(
		string keystr,
        qint64 llValue);
	void AddData2BufferString(
		string keystr,
		string strValue);

	void AddData2BufferOtherData(
		string keystr,
		void* pData,
        qint64 llDataLen);
	void Add2KVStr(string key, string strValue);
private:
    void ReallocCMDBufIfNecessary(int nNeedSize);
private:
	char*	m_pCommand;
	int		m_nCurrentSize;
	int		m_nCommandSize;
	map<string, DATAHEADER> m_mapKeyValues;
	map<string, string> m_mapKVs;
	string m_strKVs;
};

